package com.gitee.wsl.math.matrix

/**
 * A square matrix.
 */
open class SquareMatrix : MutableMatrix {
    // --------------//
    // Constructors //
    // --------------//
    /**
     * Constructor.
     *
     * @param n
     * the number of rows == the number of columns
     */
    constructor(n: Int) : super(n, n) {}

    /**
     * Constructor.
     *
     * @param m
     * the matrix (only the upper left square used)
     */
    constructor(m: MutableMatrix) {
        _set(m)
    }

    /**
     * Constructor.
     *
     * @param values
     * the array of values
     */
    constructor(values: Array<FloatArray>) {
        set(values)
    }
    // ---------//
    // Setters //
    // ---------//
    /**
     * Set this square matrix from another matrix. Note that this matrix will
     * reference the values of the argument matrix. If the values are not square,
     * only the upper left square is used.
     *
     * @param m
     * the 2-d array of values
     */
    private fun _set(m: MutableMatrix) {
        m_nCols = m.m_nRows.coerceAtMost(m.m_nCols)
        m_nRows = m_nCols
        m_aValues = m.m_aValues
    }

    /**
     * Set this square matrix from a 2-d array of values. If the values are not
     * square, only the upper left square is used.
     *
     * @param values
     * the 2-d array of values
     */
    override fun set(values: Array<FloatArray>) {
        super.set(values)
        m_nCols = m_nRows.coerceAtMost(m_nCols)
        m_nRows = m_nCols
    }
    // -------------------//
    // Matrix operations //
    // -------------------//
    /**
     * Add another square matrix to this matrix.
     *
     * @param sm
     * the square matrix addend
     * @return the sum matrix
     * @throws MatrixException
     * for invalid size
     */
    @Throws(MatrixException::class)
    fun add(sm: SquareMatrix): SquareMatrix {
        return SquareMatrix(super.add(sm))
    }

    /**
     * Subtract another square matrix from this matrix.
     *
     * @param sm
     * the square matrix subrrahend
     * @return the difference matrix
     * @throws MatrixException
     * for invalid size
     */
    @Throws(MatrixException::class)
    fun subtract(sm: SquareMatrix): SquareMatrix {
        return SquareMatrix(super.subtract(sm))
    }

    /**
     * Multiply this square matrix by another square matrix.
     *
     * @param sm
     * the square matrix multiplier
     * @return the product matrix
     * @throws MatrixException
     * for invalid size
     */
    @Throws(MatrixException::class)
    fun multiply(sm: SquareMatrix): SquareMatrix {
        return SquareMatrix(super.multiply(sm))
    }
}